package com.ccqlk.basemainapp.cqj;

import cn.hutool.core.collection.ConcurrentHashSet;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.util.*;
import java.util.concurrent.*;

@Slf4j
public class 云闪付国补抢购 {
    private static final String GUOBU_URL = "https://scene.cup.com.cn/gfmnew/appback/couponAcquire";
    private static final ObjectMapper MAPPER = new ObjectMapper();
    private static final ExecutorService EXECUTOR_SERVICE = Executors.newFixedThreadPool(200);
    private static final Set<String> CAN_STOP_CODE = new ConcurrentHashSet<>();

    @Getter
    enum User {
        王强("bj_561570b66d26cf48b80dea45635f6462e89bf9e2ff843a0d29dc0b0cdc5004a2_sh","route=1b026448294744462671c437fdfd8dac");
//        陈前进("bj_37d36270317b7d6b98c54f3b3cc41d2c71ece19359726c5472bcbf6ce0b05447_sh","route=658c31c7ad48d628966b693c45c1d6e7"),
//        袁星("sh_a6d39b82e4f6151dbd347aa1b8d8b97f97709444d3c50299194ded43304ce98d_bj","route=f619a2c397c1544357aa04bac5e8cb99");

        final String token;
        final String cookie;

        User(String token, String cookie) {
            this.token = token;
            this.cookie = cookie;
        }
    }


    @Getter
    enum Goods {
        TELEVISION("电视", "A01"),
        REFRIGERATOR("电冰箱", "A02"),
        WASHING_MACHINE("洗衣机", "A03"),
        AIR_CONDITIONER("空调", "A0401"),
        AIR_CONDITIONER_TWO("空调二", "A0402"),
        AIR_CONDITIONER_THREE("空调三", "A0403"),
        COMPUTER("电脑", "A05"),
        WATER_HEATER("热水器", "A06"),
        RANGE_HOOD("吸油烟机", "A07"),
        HOUSEHOLD_STOVE("家用灶具", "A08"),
        MICROWAVE("微波炉", "A09"),
        WATER_PURIFIER("净水器", "A10"),
        DISHWASHER("洗碗机", "A11"),
        RICE_COOKER("电饭煲", "A12");

        final String goodsName;
        final String code;

        Goods(String goodsName, String code) {
            this.goodsName = goodsName;
            this.code = code;
        }
    }

    public static void main(String[] args) throws Exception {

        // 所有用户的所有国补卷开始抢购
        List<Callable<String>> allCall = new ArrayList<>();
        for (User user : User.values()) {
            for (int i = 0; i < 5; i++) {
                allCall.addAll(Arrays.stream(Goods.values()).map(goods -> (Callable<String>) new GoGoGo(goods,user)).toList());
            }
        }

        // 主线程等待所有抢完
        List<Future<String>> futureList = EXECUTOR_SERVICE.invokeAll(allCall);
        for (Future<String> future : futureList) {
            log.info("execute result:{}", future.get());
        }

        log.info("执行完毕！请自行查看结果");
        EXECUTOR_SERVICE.shutdown();
    }


     static class GoGoGo implements Callable<String> {

        private final Goods goods;
        private final User user;

        GoGoGo(Goods goods, User user){
            this.goods = goods;
            this.user = user;
        }

         @Override
         public String call() {
             HttpRequest request = HttpUtil.createPost(GUOBU_URL);
             // 请求头
             Map<String, String> headerParams = new HashMap<>();
             {
                 headerParams.put("content-type","application/json");
                 headerParams.put("accept-language","zh-CN,zh-Hans;q=0.9");
                 headerParams.put("sec-fetch-dest","empty");
                 headerParams.put("accept","application/json, text/plain, */*");
                 headerParams.put("accept-encoding","gzip, deflate, br");
                 headerParams.put("sec-fetch-site","same-origin");
                 headerParams.put("appno","YJHX044025046");
                 headerParams.put("channelno","Q000101");
                 headerParams.put("sec-fetch-mode","cors");
                 headerParams.put("token",user.getToken());
                 headerParams.put("origin","https://scene.cup.com.cn");
                 headerParams.put("bankcode","");
                 headerParams.put("user-agent","Mozilla/5.0 (iPhone; CPU iPhone OS 16_7_10 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 /sa-sdk-ios/sensors-verify/analytics.95516.com?production   (com.unionpay.chsp) (cordova 4.5.4) (updebug 0) (version 1021) (UnionPay/1.0 CloudPay) (clientVersion 321) (language zh_CN) (languageFamily zh_CN) (upHtml) (walletMode 00)");
                 headerParams.put("referer","https://scene.cup.com.cn/gsp_front/2025/index?appNo=YJHX044025046&channelNo=Q000101");
                 headerParams.put("cookie",user.getCookie());
                 request.headerMap(headerParams,true);
             }
             // 请求参数
             String body = """
                {"areaCode": "500112","longitude": "106.4914659288195","latitude": "29.62638780381944","acquireType": "1","cateCode": "%s","activityId": null,"engGrade": null,"coordType": "gcj02ll","gpsAreaCode": "500112"}
                """.formatted(goods.getCode());
             request.body(body);

             String threadName = Thread.currentThread().getName();

             boolean stop = false;
             String respMsg = "";
             String nameByCode = goods.getGoodsName();
             while (!stop) {
                 // 其他线程已经抢到了
                 if(CAN_STOP_CODE.contains(user.name() + "-" + goods.getCode())){
                     return "thread:%s,user:%s,code:%s,name:%s,result:%s".formatted(threadName,user.name(),goods.getCode(),nameByCode,"其他线程已标记可以停止执行了.");
                 }

                 // 抢购开始
                 try {
                     log.info("user:{},code:{},name:{}\n,request data:{}",user.name(),goods.getCode(),nameByCode,body);
                     try(HttpResponse execute = request.execute()){
                         String jsonBody = execute.body();
                         log.info("user:{}, code:{},name:{}\n,response data:{}",user.name(),goods.getCode(),nameByCode,jsonBody);
                         if(jsonBody.contains("respMsg")){
                             Map<String, String> responseMap = MAPPER.readValue(jsonBody, new TypeReference<>() {});
                             respMsg = responseMap.get("respMsg");
                             stop = respMsg.contains("成功") || respMsg.contains("当日券已发完");
                         }
                     }
                     TimeUnit.MILLISECONDS.sleep(10L);
                 } catch (Exception e) {
                     log.error("execute gogogo error",e);
                 }
             }

             CAN_STOP_CODE.add(user.name() + "-" + goods.getCode());
             return "thread:%s,user:%s,code:%s,name:%s,result:%s".formatted(threadName,user.name(),goods.getCode(),nameByCode,respMsg);
         }
     }
}
